package com.ld.security.common.core.util;

import cn.hutool.core.lang.Console;
import cn.hutool.extra.emoji.EmojiUtil;
import com.ld.security.common.core.anno.CrptKey;
import com.ld.security.common.core.anno.ScriptKey;
import com.ld.security.common.core.constant.CrptCondition;
import com.ld.security.common.core.exception.ApiException;
import lombok.SneakyThrows;

import javax.script.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import static javax.script.ScriptContext.ENGINE_SCOPE;

public class ScriptUtil {

    static ScriptEngine engine;

    static ScriptEngineManager manager = new ScriptEngineManager();


    static {
      engine = manager.getEngineByName("javascript");

    }

    @SneakyThrows
    public static<E> E eval(String js){
        return (E)engine.eval(js);
    }

    /**
     *
     * @param js 函数体代码
     * @param params 函数体参数
     * @param <E>
     * @return
     */
    @SneakyThrows
    public static<E> E runFunc(String js,Map<String,Object> params) {
        Object[] vs =  new Object[params.size()];
        int i = 0;
        String func ="function func(";
        boolean b = false;
        for (String s : params.keySet()) {
            if(b){
                func+=",";
            }else{
                b=true;
            }
            func+=s;
            vs[i++]=params.get(s);
        }
        func+="){"+js+"}";
        ScriptEngine scriptEngine = manager.getEngineByName("javascript");
        scriptEngine.eval(func);
        Invocable invocable =(Invocable) scriptEngine;

       Object val =  invocable.invokeFunction("func",vs);
        return (E)val;
    }

        @SneakyThrows
    public static<E> E eval(String js,Map<String,Object> params){
        SimpleScriptContext content = new SimpleScriptContext();
        for (String key : params.keySet()) {
            Object val =  params.get(key);
            content.setAttribute(key,val,ENGINE_SCOPE);
        }

        Object v =  engine.eval(js,content);
        return (E)v;
    }
    /**
     * 对象处理
     * @param
     * @return
     */
    public static Object apply(Object obj){
        Map params =  ReflectionUtil.clone(obj,HashMap.class);
        for (Field field : ReflectionUtil.getAllDeclaredFields(obj.getClass())) {
            ScriptKey scriptKey = field.getAnnotation(ScriptKey.class);
            if(scriptKey == null){
                continue;
            }
            String js = TemplateUtil.renderString(scriptKey.value(),params);
            Object v =  eval(js);

            ReflectionUtil.invokeSetter(obj,field.getName(),v);
        }

        return obj;
    }




}
